#include<linux/module.h>
#include<linux/gpio.h>
#include<linux/timer.h>

#define GPIO_PIN 21

static struct timer_list gpio_timer;

static void gpio_timer_callback(struct timer_list *t){
	static bool gpio_state=0;

	gpio_state=gpio_state==0?1:0;
	gpio_set_value(GPIO_PIN,gpio_state);

	mod_timer(&gpio_timer,jiffies+msecs_to_jiffies(200));
}

static int __init v_init(void){
	int ret;

	ret=gpio_request(GPIO_PIN,"GPIO_PIN_21");
	if(ret){
		printk(KERN_ERR "Failed to request GPIO %d\n",GPIO_PIN);
		return ret;
	}

	ret=gpio_direction_output(GPIO_PIN,0);
	if(ret){
		printk(KERN_ERR "Failed to set GPIO %d as output\n",GPIO_PIN);
		gpio_free(GPIO_PIN);
		return ret;
	}

	timer_setup(&gpio_timer,gpio_timer_callback,0);

	mod_timer(&gpio_timer,jiffies+msecs_to_jiffies(200));

	printk("GPIO %d is now toggling.\n",GPIO_PIN);
	return 0;
}

static void __exit v_exit(void){
	del_timer_sync(&gpio_timer);

	gpio_free(GPIO_PIN);
	printk("GPIO %d is removed.\n",GPIO_PIN);
}

module_init(v_init);
module_exit(v_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhuzonghui <puchuchen@outlook.com>");
MODULE_DESCRIPTION("This module is trun 0/1");
